package android.bluebox.view;

import java.util.ArrayList;
import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluebox.R;
import android.bluebox.model.LocationResult;
import android.bluebox.model.StaticBox;
import android.bluebox.model.Workspace;
import android.bluebox.model.WorkspaceDetailCustomBaseAdapter;
import android.bluebox.model.WorkspaceDetailItem;
import android.content.Context;
import android.content.DialogInterface;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class WorkspaceDetailView extends Activity {

	static int NEW_WORKSPACE = 0;
	static int EDIT_WORKSPACE = 1;

	Context thisContext;

	int ws_id_requested;

	LocationResult currentLocation = new LocationResult(-1, -1);

	LocationManager mlocManager;
	LocationListener mlocListener;

	boolean foundLocation = false;

	Button btnSave;
	Button btnCancel;

	ListView lvDetail;
	ArrayList<WorkspaceDetailItem> workspaceDetailList = new ArrayList<WorkspaceDetailItem>();
	WorkspaceDetailCustomBaseAdapter cba;

	Workspace wsRequested = null;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.workspacedetail);
		thisContext = this.getBaseContext();

		btnSave = (Button) findViewById(R.id.wsd_btn_save);
		btnSave.setOnClickListener(saveWorkspace);

		btnCancel = (Button) findViewById(R.id.wsd_btn_canel);
		btnCancel.setOnClickListener(cancel);

		StaticBox.dbBox.setContext(this);

		loadDetail();
		lvDetail = (ListView) findViewById(R.id.wsd_list);
		cba = new WorkspaceDetailCustomBaseAdapter(this, workspaceDetailList);
		lvDetail.setAdapter(cba);
		lvDetail.setOnItemClickListener(changeValue);
	}

	public void loadDetail() {

		WorkspaceDetailItem wdItem = new WorkspaceDetailItem();
		wdItem.setTitle("Name");
		workspaceDetailList.add(wdItem);

		wdItem = new WorkspaceDetailItem();
		wdItem.setTitle("Network");
		workspaceDetailList.add(wdItem);

		wdItem = new WorkspaceDetailItem();
		wdItem.setTitle("Location");
		workspaceDetailList.add(wdItem);

		ws_id_requested = this.getIntent().getExtras().getInt("wsId");

		/*
		 * Load data if editing
		 */
		if (ws_id_requested != 0) {
			wsRequested = StaticBox.dbBox.getWorkspace(ws_id_requested);
			workspaceDetailList.get(0).setValue(wsRequested.getName());
			workspaceDetailList.get(1).setValue(wsRequested.getHostIP());
			workspaceDetailList.get(2).setValue(wsRequested.getStringLocation());
		}
	}

	public void refreshList() {
		cba.setArraylist(workspaceDetailList);
		cba.notifyDataSetChanged();
		lvDetail.setAdapter(cba);
	}

	public void getNewName(String currentName) {
		AlertDialog.Builder alertFindServer = new AlertDialog.Builder(this);
		alertFindServer.setTitle("Workspace");
		alertFindServer.setMessage("New name");

		// Set an EditText view to get user Input
		final EditText edtName = new EditText(this);
		edtName.setText(currentName);
		alertFindServer.setView(edtName);

		alertFindServer.setPositiveButton("Done", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int button) {

				String newName = edtName.getText().toString().trim();
				if (newName.length() > 0) {
					workspaceDetailList.get(0).setValue(newName);
					refreshList();
				} else {
					Toast.makeText(getBaseContext(), "Please input server IP",
							Toast.LENGTH_SHORT).show();
				}
			}
		});

		alertFindServer.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int button) {
			}
		});
		alertFindServer.show();
	}

	public void getNewServer() {
		AlertDialog.Builder alertFindServer = new AlertDialog.Builder(this);
		alertFindServer.setTitle("Find server");
		alertFindServer.setMessage("Server IP");

		// Set an EditText view to get user Input
		final EditText edtIP = new EditText(this);
		edtIP.setText(workspaceDetailList.get(1).getValue());
		alertFindServer.setView(edtIP);

		alertFindServer.setPositiveButton("Find", new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int button) {
				String IP = edtIP.getText().toString().trim();
				if (IP.length() > 0) {
					findingServer(IP);
					refreshList();
				} else {
					Toast.makeText(getBaseContext(), "Please input server IP",
							Toast.LENGTH_SHORT).show();
				}
			}
		});

		alertFindServer.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int button) {
			}
		});
		alertFindServer.show();
	}

	public OnItemClickListener changeValue = new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> a, View v, int position, long id) {

			switch(position) {
			/*
			 * Edit Workspace name
			 */
			case 0:
				getNewName(workspaceDetailList.get(0).getValue());
				break;

			case 1:
				getNewServer();
				break;

			case 2:
				getNewGPS();
				new LocationControl().execute(getApplicationContext());
				refreshList();
				break;
			}
		}
	};

	private OnClickListener saveWorkspace = new OnClickListener() {

		@Override
		public void onClick(View arg0) {

			String newName = workspaceDetailList.get(0).getValue();

			if (newName.equals("")) {
				Toast.makeText(getBaseContext(), "Enter name of workspace", Toast.LENGTH_SHORT).show();
			} else if (ws_id_requested != 0 && newName.equals(wsRequested.getName())) {
				Workspace ws = new Workspace();
				ws.setId(ws_id_requested);
				ws.setName(newName);
				ws.setHostIP(workspaceDetailList.get(1).getValue());
				ws.setLocation(currentLocation);
				ws.setLastVisited(wsRequested.getLastVisited());

				StaticBox.dbBox.updateWorkspace(ws);

				Toast.makeText(getBaseContext(), "Workspace Saved", Toast.LENGTH_LONG).show();
				finish();
			} else if (StaticBox.dbBox.getWorkspace(newName) != null) {
				Toast.makeText(getBaseContext(),"This workspace name existed", Toast.LENGTH_SHORT).show();
			} else {
				Workspace ws = new Workspace();
				ws.setName(newName);
				ws.setHostIP(workspaceDetailList.get(1).getValue());
				ws.setLocation(currentLocation);

				if (ws_id_requested == 0) {
					ws.setLastVisited("never logged");
					StaticBox.dbBox.insertWorkspace(ws);
				} else {
					ws.setId(ws_id_requested);
					ws.setLastVisited(wsRequested.getLastVisited());
					StaticBox.dbBox.updateWorkspace(ws);
				}
				Toast.makeText(getBaseContext(), "Workspace Saved", Toast.LENGTH_LONG).show();
				WorkspaceDetailView.this.setResult(RESULT_OK);
				finish();
			}
		}
	};

	private OnClickListener cancel = new OnClickListener() {

		@Override
		public void onClick(View arg0) {
			finish();
		}
	};

	public void findingServer(String IP) {
		new FindingServer().execute(IP);
	}

	public class FindingServer extends AsyncTask<String, Void, Boolean> {

		private final ProgressDialog dialog = new ProgressDialog(WorkspaceDetailView.this);

		protected void onPreExecute() {
			this.dialog.setTitle("Searching server");
			this.dialog.setMessage("Please wait...");
			this.dialog.show();
		}

		@Override
		protected Boolean doInBackground(String... hostIP) {
			workspaceDetailList.get(1).setValue(hostIP[0]);
			return StaticBox.netBox.findAvailableWorkspace(hostIP[0]);
		}

		protected void onProgressUpdate(final Void unused) {
		}

		protected void onPostExecute(boolean foundHost) {
			if (this.dialog.isShowing())
				this.dialog.dismiss();

			if (foundHost) {
				refreshList();
				Toast.makeText(thisContext, "Server found", Toast.LENGTH_SHORT).show();		
			} else {
				Toast.makeText(thisContext, "Server not found", Toast.LENGTH_SHORT).show();
			}
		}
	}

	protected void onResume() {
		super.onResume();
		refreshList();
	}

	/*
	 * GPS ZONE
	 */
	public void getNewGPS() {
		mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		mlocListener = new MyLocationListener();
		mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
		mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mlocListener);
	}

	public void removeUpdates() {
		mlocManager.removeUpdates(mlocListener);
	}

	public void update() {
		mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
		mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mlocListener);
	}

	public class MyLocationListener implements LocationListener {
		public void onLocationChanged(Location loc) {
			float latitude = (float) loc.getLatitude();
			float longitude = (float) loc.getLongitude();
			currentLocation = new LocationResult(latitude, longitude);
			foundLocation = true;
			removeUpdates();
		}

		@Override
		public void onProviderDisabled(String provider) {
			Toast.makeText(getApplicationContext(), "Gps Disable", Toast.LENGTH_SHORT).show();

		}

		@Override
		public void onProviderEnabled(String provider) {
			Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	private class LocationControl extends AsyncTask<Context, Void, Void> {
		private final ProgressDialog dialog = new ProgressDialog(WorkspaceDetailView.this);
		protected void onPreExecute() {
			this.dialog.setTitle("Searching location");
			this.dialog.setMessage("Please wait...");
			this.dialog.show();
			foundLocation = false;
		}

		@Override
		protected Void doInBackground(Context... params) {
			Long t = Calendar.getInstance().getTimeInMillis();
			while (!foundLocation && Calendar.getInstance().getTimeInMillis() - t < 15000) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		protected void onPostExecute(final Void unused)
		{
			if(this.dialog.isShowing()) {
				this.dialog.dismiss();
			}
			if (currentLocation.getLatitude() > 0)
			{
				workspaceDetailList.get(2).setValue("Latitude: " + currentLocation.getLatitude() + "\nLogitute: " + currentLocation.getLongitude());
				refreshList();
			}
			else
			{
				StaticBox.makeToast(getBaseContext(), "can not detect location");
			}
			removeUpdates();
		}
	}

	/*
	 * END OF GPS ZONE
	 */
}
